/*

  xmunipack - preferences


  Copyright © 2010-2011 F.Hroch (hroch@physics.muni.cz)

  This file is part of Munipack.

  Munipack is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.
  
  Munipack is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  
  You should have received a copy of the GNU General Public License
  along with Munipack.  If not, see <http://www.gnu.org/licenses/>.


  Notes.

  The derivation from wxPropertySheetDialog has stranges:
     - default constructor must not be called
     - validation and style style set work just only when
       Create is called after SetExtraStyle and SetSheetStyle
     - Style shrinkof works horribly for (almost) emtpy tab

*/

#include "xmunipack.h"
#include <wx/wx.h>
#include <wx/valgen.h>

using namespace std;


MuniPreferences::MuniPreferences(wxWindow *w, MuniConfig *c):
  config(c)
{
  SetExtraStyle(wxWS_EX_VALIDATE_RECURSIVELY);

  Init();

  SetSheetStyle(wxPROPSHEET_TOOLBOOK/*|wxPROPSHEET_SHRINKTOFIT*/);
  Create(w,wxID_ANY,wxEmptyString);

  const int is = 22;
  MuniArtIcons ico(wxART_TOOLBAR,wxSize(is,is));
  wxImageList *icons = new wxImageList(is, is, true);
  icons->Add(ico.Icon(wxART_HELP));
  icons->Add(ico.Icon(wxART_INFORMATION));
  icons->Add(ico.Icon(wxART_HELP_PAGE));

  wxBookCtrlBase* book = GetBookCtrl();
  book->AssignImageList(icons);
  book->AddPage(CreateGeneral(book),"General",true,0);
  book->AddPage(CreateKeywords(book),"Keywords",false,1);
  book->AddPage(CreateColors(book),"Colors",false,2);

  LayoutDialog();

  Bind(wxEVT_IDLE,&MuniPreferences::OnIdle,this);
  Bind(wxEVT_CLOSE_WINDOW,&MuniPreferences::OnClose,this,GetId());
}

void MuniPreferences::OnClose(wxCloseEvent& event)
{
  if ( Validate() && TransferDataFromWindow() ) {

    double x;
    if( uwhite.ToDouble(&x) )
      config->color_uwhitepoint = x;
    if( vwhite.ToDouble(&x) )
      config->color_vwhitepoint = x;
  }

  wxQueueEvent(GetParent(),new wxCommandEvent(EVT_CONFIG_UPDATED));

  Destroy();
}

void MuniPreferences::Init()
{
  uwhite.Printf("%.4f",config->color_uwhitepoint);
  vwhite.Printf("%.4f",config->color_vwhitepoint);
}


wxPanel *MuniPreferences::CreateGeneral(wxWindow *w)
{
  wxPanel *panel = new wxPanel(w);

  wxBoxSizer *topsizer = new wxBoxSizer(wxVERTICAL);
  topsizer->Add(new wxStaticText(panel,wxID_ANY,"General is not available."),
wxSizerFlags(1).Align(wxALIGN_CENTER|wxALIGN_CENTER_VERTICAL).TripleBorder());
  panel->SetSizer(topsizer);
  topsizer->Fit(panel);
  
  return panel;
}

wxPanel *MuniPreferences::CreateKeywords(wxWindow *w)
{
  wxFont bf(*wxNORMAL_FONT);
  bf.SetWeight(wxFONTWEIGHT_BOLD);

  wxSizerFlags label_sizer;
  label_sizer.Align(wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT);

  wxSizerFlags control_sizer(1);
  control_sizer.Align(wxALIGN_CENTER_VERTICAL).Border(wxLEFT|wxRIGHT).Expand();

  wxPanel *panel = new wxPanel(w);

  wxStaticText *label = new wxStaticText(panel,wxID_ANY,"FITS Keywords:");
  label->SetFont(bf);

  wxFlexGridSizer *sgrid = new wxFlexGridSizer(2);
  sgrid->AddGrowableCol(1);

  sgrid->Add(new wxStaticText(panel,wxID_ANY,"Object:"),
	     label_sizer);
  wxTextCtrl *tobject = new wxTextCtrl(panel,wxID_ANY);
  sgrid->Add(tobject,control_sizer);

  sgrid->Add(new wxStaticText(panel,wxID_ANY,"Observer:"),
	     label_sizer);
  wxTextCtrl *tobser = new wxTextCtrl(panel,wxID_ANY);
  sgrid->Add(tobser,control_sizer);

  sgrid->Add(new wxStaticText(panel,wxID_ANY,"Date-obs:"),
	     label_sizer);
  wxTextCtrl *tdate = new wxTextCtrl(panel,wxID_ANY);
  sgrid->Add(tdate,control_sizer);
 
  sgrid->Add(new wxStaticText(panel,wxID_ANY,"Exposure:"),
	     label_sizer);
  wxTextCtrl *texp = new wxTextCtrl(panel,wxID_ANY);
  sgrid->Add(texp,control_sizer);

  sgrid->Add(new wxStaticText(panel,wxID_ANY,"Filter:"),
	     label_sizer);
  wxTextCtrl *tfilter = new wxTextCtrl(panel,wxID_ANY);
  sgrid->Add(tfilter,control_sizer);

  wxBoxSizer *topsizer = new wxBoxSizer(wxVERTICAL);
  topsizer->Add(label,wxSizerFlags().Align(wxALIGN_CENTER).Border());
  topsizer->Add(sgrid,wxSizerFlags().Expand());
  panel->SetSizer(topsizer);
  topsizer->Fit(panel);

  tobject->SetValidator(wxTextValidator(wxFILTER_NONE,&config->fits_object));
  tobser->SetValidator(wxTextValidator(wxFILTER_NONE,&config->fits_observer));
  tdate->SetValidator(wxTextValidator(wxFILTER_NONE,&config->fits_dateobs));
  texp->SetValidator(wxTextValidator(wxFILTER_NONE,&config->fits_exposure));
  tfilter->SetValidator(wxTextValidator(wxFILTER_NONE,&config->fits_filter));

  return panel;
}

wxPanel *MuniPreferences::CreateColors(wxWindow *w)
{
  wxSizerFlags label_sizer;
  label_sizer.Align(wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT);

  wxSizerFlags vsizer(1);
  vsizer.Align(wxALIGN_CENTER_VERTICAL).Border(wxLEFT|wxRIGHT).Expand();


  wxPanel *panel = new wxPanel(w);
  
  wxFlexGridSizer *ocsgrid = new wxFlexGridSizer(2);
  ocsgrid->AddGrowableCol(1);

  ocsgrid->Add(new wxStaticText(panel, wxID_ANY,"Display Color Space:"),wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL|wxALIGN_RIGHT));

  FitsDisplay display(config->display_colorspace);
  ocs = new wxChoice(panel,ID_CHOICE_COLORSPACE,wxDefaultPosition,
		     wxDefaultSize,display.GetArraySpaces());
  ocsgrid->Add(ocs,wxSizerFlags().Align(wxALIGN_CENTER_VERTICAL|wxALIGN_LEFT).
	       Border());

  wxFlexGridSizer *sgrid = new wxFlexGridSizer(2);
  sgrid->AddGrowableCol(1);

  sgrid->Add(new wxStaticText(panel, wxID_ANY,"Temperature:"),label_sizer);
  temper = new wxSpinCtrl(panel,wxID_ANY);
  temper->SetRange(4000,25000);
  temper->SetValue(config->color_temperature);
  sgrid->Add(temper,vsizer);

  sgrid->Add(new wxStaticText(panel, wxID_ANY,"White point u:"),label_sizer);
  tu = new wxTextCtrl(panel,wxID_ANY);
  sgrid->Add(tu,vsizer);

  sgrid->Add(new wxStaticText(panel, wxID_ANY,"White point v:"),label_sizer);
  tv = new wxTextCtrl(panel,wxID_ANY);
  sgrid->Add(tv,vsizer);

  wxButton *butt = new wxButton(panel,wxID_ANY,"Reset");

  wxBoxSizer *topsizer = new wxBoxSizer(wxVERTICAL);
  topsizer->Add(ocsgrid,wxSizerFlags().Border().Center());
  topsizer->Add(sgrid,wxSizerFlags().Border().Expand());
  topsizer->Add(butt,wxSizerFlags().Border().Center());
  panel->SetSizer(topsizer);
  topsizer->Fit(panel);

  ocs->SetValidator(wxGenericValidator(&config->display_colorspace));
  tu->SetValidator(wxTextValidator(wxFILTER_NUMERIC,&uwhite));
  tv->SetValidator(wxTextValidator(wxFILTER_NUMERIC,&vwhite));
  Bind(wxEVT_COMMAND_SPINCTRL_UPDATED,&MuniPreferences::OnColorTemper,this,temper->GetId());
  Bind(wxEVT_COMMAND_BUTTON_CLICKED,&MuniPreferences::OnColorReset,this,butt->GetId());
  return panel;
}


void MuniPreferences::OnIdle(wxIdleEvent& event)
{
  int n = GetBookCtrl()->GetSelection();
  if( n >= 0 )
    SetTitle(GetBookCtrl()->GetPageText(n));
}

void MuniPreferences::OnColorTemper(wxSpinEvent& event)
{
  config->color_temperature = event.GetPosition();
}

void MuniPreferences::OnColorReset(wxCommandEvent& event)
{
  temper->SetValue(6504);
  tu->SetValue("0.19784");
  tv->SetValue("0.46831");
  ocs->SetSelection(0);
  config->color_temperature = 6504.0;
  config->color_uwhitepoint = 0.19784;
  config->color_vwhitepoint = 0.46831;
  config->display_colorspace = "sRGB";
}
